package cn.yitun.chat.yitunservermanagecore.general.manage.system.service.impl;

import cn.yitun.chat.yituncommonmessage.ExceptionEnum;
import cn.yitun.chat.yituncommonmessage.YitunException;
import cn.yitun.chat.yituncommonutil.YitunMD5Util;
import cn.yitun.chat.yituncommonutil.YitunMapUtil;
import cn.yitun.chat.yituncommonutil.YitunStringUtil;
import cn.yitun.chat.yitunservercommonlib.constant.Constants;
import cn.yitun.chat.yitunservercommonlib.crud.yitun.CrudServiceImpl;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.system.user.ResetPwdDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.system.user.UserDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.userchat.UserHeadDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.userchat.UserNumberDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.UserRoleInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.user.UserInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.user.UserVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.userchat.UserHeadVo;
import cn.yitun.chat.yitunservercommonlib.enums.userChat.UserHeadTypeEnums;
import cn.yitun.chat.yitunservercommonlib.util.PinYinUtil;
import cn.yitun.chat.yitunservercommonlib.util.R;
import cn.yitun.chat.yitunservercommonlib.util.codec.IdGen;
import cn.yitun.chat.yitunserverimbase.dao.system.UserDao;
import cn.yitun.chat.yitunserverimbase.dao.system.UserRoleDao;
import cn.yitun.chat.yitunserverimbase.dao.userchat.UserHeadDao;
import cn.yitun.chat.yitunserverimbase.dao.userchat.UserNumberDao;
import cn.yitun.chat.yitunservermanagecore.general.manage.system.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 
 * date 2018-07-17 22:39:50<br>
 * description
 * 
 * @author yitun<br>
 * @since
 */
@Service
@Transactional
public class UserServiceImpl
		extends CrudServiceImpl<UserDao,UserDto, UserInfo, UserVo>
		implements UserService {

	@Resource
	private UserRoleDao userRoleDAO;
	@Resource
	private UserNumberDao numberDAO;
	@Resource
	private UserHeadDao userHeadDao;
	/**
	 * 跟据id获取用户实体
	 * 
	 * @param id
	 * @return
	 */
	@Override
	public UserInfo getById(Long id) {
		return dao.get(id);
	}
	@Override
	public UserVo getVo(Long id) {
		return dao.getVO(id);
	}

	/**
	 * 用户新增
	 * @param user
	 * @return
	 */
	@Transactional
	@Override
	public int save(UserDto user) {
		//默认code,privateKey
		user.setCode(IdGen.uuid());
		user.setPrivateKey(IdGen.uuid());
		if (YitunStringUtil.isNotEmpty(user.getNickname())) user.setNickname(user.getName());
		user.setSimpleSpell(PinYinUtil.getFirstSpell(user.getName()));
		user.setSpell(PinYinUtil.getFullSpell(user.getName()));
		int count = super.save(user);
		Long id = user.getId();
		List<Long> roles = user.getRoleIds();
		List<UserRoleInfo> list = new ArrayList<>();
		saveUserRole(roles, list, id );
		return count;
	}

	/**
	 * 用户更新
	 * @param user
	 * @return
	 */
	@Transactional
	@Override
	public int update(UserDto user) {
		//拼音
		user.setSimpleSpell(PinYinUtil.getFirstSpell(user.getName()));
		user.setSpell(PinYinUtil.getFullSpell(user.getName()));
		//用户头像
		saveHead(user.getUserHead(), user.getId());
		int r = dao.update(user);
		if(r > 0) {
			Long userId = user.getId();
			List<Long> roles = user.getRoleIds();
			// 处理用户角色
			userRoleDAO.deleteByUserId(userId);
			List<UserRoleInfo> list = new ArrayList<>();
			saveUserRole(roles, list, userId);
		}
		return r;
	}

	/**
	 * 更新用户角色关联表数据
	 * @param roles
	 * @param list
	 * @param userId
	 */
	@Transactional
	public void saveUserRole(List<Long> roles, List<UserRoleInfo> list, Long userId ) {
		for (Long roleId : roles) {
			UserRoleInfo ur = new UserRoleInfo();
			ur.setUserId(userId);
			ur.setRoleId(roleId);
			list.add(ur);
		}
		if (list.size() > 0) {
			userRoleDAO.batchSave(list);
		}
	}

	/**
	 * 根据id是否存在执行新增或者修改
	 *
	 * @param user
	 */
	@Override
	@Transactional
	public void addOrUpdate(UserDto user, List<Long> roleIds) {
		addOrUpdate(user);
		addOrUpdate(user.getId(), roleIds);
	}
	@Transactional
	public void addOrUpdate(UserDto user) {
		if (null == user.getId() || "".equals(user.getId())) {
			long i = Constants.baseRandomLong + new Random().nextLong();
			UserNumberDto userNumber = new UserNumberDto();// 生成数子账号
			userNumber.setCode(IdGen.uuid());
			numberDAO.save(userNumber);

			user.setCode(userNumber.getCode());
			user.setHead(i);
			user.setPassword(YitunMD5Util.md5L32(user.getPassword()));
			dao.save(user);
		} else {
			dao.update(user);
		}
	}
	@Transactional
	public void addOrUpdate(Long userId, List<Long> roleIds) {
		List<UserRoleInfo> rmList = userRoleDAO.list(R.param("userId", userId));

		List<UserRoleInfo> deleteList = new ArrayList<>();

		Map<Long, UserRoleInfo> map = new HashMap<>();
		for (UserRoleInfo ur : rmList) {
			if (map.containsKey(ur.getRoleId())) {
				deleteList.add(ur);
			}
			map.put(ur.getRoleId(), ur);
		}

		List<UserRoleInfo> addList = new ArrayList<UserRoleInfo>();
		for (Long roleId : roleIds) {
			UserRoleInfo rm = map.remove(roleId);
			if (null == rm) {
				rm = new UserRoleInfo();
				rm.setRoleId(roleId);
				rm.setUserId(userId);
				addList.add(rm);
			}
		}
		deleteList.addAll(map.values());
		if (!addList.isEmpty()) {
			for (UserRoleInfo ur : addList) {
				userRoleDAO.save(ur);
			}
		}

		if (!deleteList.isEmpty()) {
			for (UserRoleInfo ur : deleteList) {
				userRoleDAO.remove(ur.getId());
			}
		}
	}

	/**
	 * 查询用户()
	 * 
	 * @param userQuery
	 * @return
	 */
	@Override
	public List<UserVo> queryUserDataList(UserDto userQuery) {
		List<UserVo> list = dao.listVO(YitunMapUtil.java2Map(userQuery, false));

		List<Long> userIdList = new ArrayList<>();
		Map<Long, UserVo> map = new HashMap<>();
		for (UserVo ud : list) {
			userIdList.add(ud.getId());
			map.put(ud.getId(), ud);
		}
		List<UserRoleInfo> urs = userRoleDAO.getListByUserIdList(userIdList);

		for (UserRoleInfo ur : urs) {
			UserVo ud = map.get(ur.getUserId());
			if (null != ud) {
				List<UserRoleInfo> userRoleList = ud.getUserRoleInfoList();
				if (null == userRoleList) {
					userRoleList = new ArrayList<>();
					ud.setUserRoleInfoList(userRoleList);
				}
				userRoleList.add(ur);
			}
		}
		return list;
	}

	/**
	 * 根据id删除用户
	 * 
	 * @param id
	 */
	@Override
	public void delete(Long id) {
		dao.remove(id);
		userRoleDAO.deleteByUserId(id);
	}
	@Override
	public UserInfo getUserByAccount(String account) {
		return dao.getUserByAccount(account);
	}
	@Override
	public UserVo getUserVoByAccount(String account) {
		return dao.getUserVoByAccount(account);
	}
	@Override
	public boolean isExistAccount(String account, Long id) {
		boolean isExist = true;
		UserInfo data = dao.getUserByAccount(account);
		if (null == data || null == id) {
			isExist = false;
		}
		return isExist;
	}
	@Override
	public int updatePassword(Long userId, String password) {
		password = YitunMD5Util.md5L32(password);
		int mark = dao.updatePassword(userId, password);
		return mark;
	}
	
	/**
	 * 修改用户类型
	 * @param userId
	 * @param type
	 * @return
	 */
	@Override
	public int updateType(Long userId, String type) {
		int mark = dao.updateType(userId, type);
		return mark;
	}

	/**
	 * 获取系统用户的角色列表 date 2018-07-18 09:29:20<br>
	 * description
	 * 
	 * @author yitun<br>
	 * @param userId
	 * @return
	 * @since
	 */
	@Override
	public List<UserRoleInfo> getUserRoleInfoListByUserId(Long userId) {
		List<Long> userIdList = new ArrayList<>();
		userIdList.add(userId);
		List<UserRoleInfo> urs = userRoleDAO.getListByUserIdList(userIdList);
		return urs;
	}

	/**
	 * 更新个人信息
	 * @param userDto
	 * @return
	 */
	@Override
	@Transactional
	public int updatePersonal(UserDto userDto, UserHeadDto userHead) {
		//用户头像
		saveHead(userHead, userDto.getId());
		return dao.updatePersonal(userDto);
	}

	/**
	 * 处理用户头像
	 * @param newHead
	 * @param userId
	 */
	@Transactional
	public void saveHead(UserHeadDto newHead, Long userId) {
		if (newHead != null) {
			UserHeadVo oldHead = userHeadDao.getLastByUserId(userId);
			if (oldHead != null)
				userHeadDao.remove(oldHead.getId());
			newHead.setUserId(userId);
			newHead.setCreateBy(userId);
			newHead.setUpdateBy(userId);
			if (YitunStringUtil.isEmpty(newHead.getType()))
				newHead.setType(UserHeadTypeEnums.TYPE_SYSTEM.getType());
			userHeadDao.save(newHead);
		}
	}


	/**
	 * 修改密码
	 * @param resetPwdDto
	 * @param userDO
	 * @return
	 */
	@Transactional
	@Override
	public int resetPwd(ResetPwdDto resetPwdDto, UserInfo userDO)  {
		if (Objects.equals(resetPwdDto.getId(), userDO.getId())) {
			if ( YitunMD5Util.md5L32(resetPwdDto.getOldPassword()).equals(userDO.getPassword() )) {
				userDO.setPassword(YitunMD5Util.md5L32( resetPwdDto.getNewPassword()));
				return dao.updatePassword(userDO.getId(), userDO.getPassword());
			} else
				throw new YitunException( ExceptionEnum.USER_PASSWORD_FALSE );
		} else
			throw new YitunException(ExceptionEnum.NOT_CURRENT);
	}
	/**
	 * 管理员修改用户密码
	 * @param resetPwdDto
	 * @return
	 */
	@Transactional
	@Override
	public int adminResetPwd(ResetPwdDto resetPwdDto) {
		UserInfo userDO = get(resetPwdDto.getId());
		userDO.setPassword(YitunMD5Util.md5L32(resetPwdDto.getNewPassword()));
		return dao.updatePassword(userDO.getId(), userDO.getPassword());
	}

}
